<template>
  <!-- 设置上传头像的样式 -->
  <div class="my-img-upload">
    <!-- 调用饿了么ui 上传组件 并且绑定一些上传属性 -->
    <el-upload :http-request="handleUpload" :before-upload="beforeUpload" :auto-upload="true" :on-change="handleChange" :on-remove="handleRemove" list-type="picture-card" :class="{'hide-plus': imgLen}" :limit="limit" action="#" :on-preview="preview" :file-list="fileList">
      <!-- list-type表示上传组件的布局形式(饿了么ui提供) -->
      <!-- :class 动态设置上传后隐藏添加按钮的css样式(动态对象设置css类名 :class={'css样式名':计算属性名判断是否满足条件布尔类型}) -->
      <!-- :limit表示允许上传的文件个数 -->
      <!-- action表示默认上传的图片地址 如果是自定义上传 可以设置为# action="#" -->
      <!-- :file-list表示显示的图片列表 (图片储存的对象) -->
      <!-- :on-preview控制图片预览大图效果 可以设置传递图片的信息的参数 -->
      <!-- :on-remove是绑定删除图片的指令 具有两个参数   参数一表示当前删除的图片信息 参数二表示删除后剩余的图片信息 -->
      <!-- :on-change是绑定添加图片的指令 具有两个参数   参数一表示新选中上传的文件 参数二表示选中之后剩余的列表 -->
      <!-- :auto-upload是设置是否自动上传(布尔类型) -->
      <!-- :before-upload上传文件之前的钩子 自带一个参数 获取上传图片的类型大小信息用于效验 -->
      <!-- :http-request 覆盖默认的上传行为，可以自定义上传的实现 自带一个参数 获取图片上传的相关数据 类似于:before-upload效验 (必须把:auto-upload自动上传设置为true) -->
      <i class="el-icon-plus avatar-uploader-icon" />
    </el-upload>
    <!-- 图片预览层 -->
    <!-- :visible.sync设置控制图片预览大图弹窗的显示(显示弹窗预览图) -->
    <el-dialog width="600px" top="8vh" title="图片预览" :visible.sync="showDialog">
      <!-- 动态绑定图片的url地址实现和头像地址一致 -->
      <img width="100%" :src="imgUrl" alt="">
    </el-dialog>
    <!-- 控制上传图片进度条加载状态 -->
    <div v-if="isShow">上传进度：
      <el-progress style="width: 180px;" :percentage="percent" />
      <!-- :percentage是设置进度条的百分比 -->
    </div>
  </div>
</template>
<script>
// 导入腾讯云的包(sdk)
import COS from 'cos-js-sdk-v5'
// 手动设置上传到腾讯云的秘钥
const cos = new COS({
  SecretId: 'AKIDRfeOs76rNdgU4NPBgurXx5wWqsd8NL2S', // 身份识别 ID
  SecretKey: 'A3f05uSihQs4ycz5tQgfNoyrTnqc7LxJ' // 身份密钥
})
export default {
  name: 'ImageUpload',
  props: {
    limit: {
      type: Number,
      required: true
    },
    defaultImg: {
      required: false
    },
    isok: {
      required: true
    }
  },
  data () {
    return {
      // 设置进度条的百分比(默认为0)
      percent: 0,
      // 控制进度条的加载状态位
      isShow: false,
      // 控制预览弹窗效果
      showDialog: false,
      // 预览图片
      imgUrl: '',
      // 默认的图片列表地址
      fileList: []
    }
  },
  computed: {
    // 获取图片列表长度进行判断设置相应的css样式(大于一张 隐藏添加按钮样式 小于一张显示添加按钮样式)
    imgLen () {
      return this.fileList.length >= this.limit
    }
  },
  watch: {
    // 监听子组件传来的上传头像数据 储存到图片列表中
    defaultImg (src) {
      this.fileList = [{ url: this.defaultImg }]
    }
  },
  methods: {
    // 把图片上传到腾讯云
    handleUpload (params) {
      // 判断上传的数据是否存在(进行图片效验)
      if (params.file) {
        // 通过腾讯云秘钥进行上传(腾讯云提供的方法)
        cos.putObject({
          Bucket: 'jinyanlong-1305883696', /* 存储桶的名称 必须字段*/
          Region: 'ap-hongkong', /* 存储桶所在地域，必须字段 */
          Key: params.file.name, /* 文件名 */
          StorageClass: 'STANDARD', // 上传模式, 标准模式(默认)
          Body: params.file, // 上传文件对象
          // 上传的进度(可以设置进度条 支持进度条设置)
          onProgress: (progressData) => {
            console.log(JSON.stringify(progressData))
            // 上传开始时候 显示进度条
            this.isShow = true
            this.$emit('isokNowxs')
            // 计算进度条的进度 进行赋值(腾讯云提供的是小数进度 需要*100 可以向下取整显示整数)
            this.percent = Math.floor(progressData.percent * 100)
            // 到达1的时候 说明上传成功
            if (progressData.percent === 1) {
              // 添加定时器 上传成功后 进行缓冲
              // 进度完成
              this.isShow = false
              // 上传完成 重置进度条
              this.percent = 0
              // 开启上传按钮
              this.$emit('isokNow')
            }
          }
        }, (err, data) => { // err是错误信息 data是上传成功后返回的数据
          // 上传成功的回调
          console.log(err || data)
          // err是上传失败回调
          // 判断是否上传失败
          if (err) {
            this.$message.error('图片上传失败')
          }
          // data表示的是上传成功后的回调
          // 上传成功后 需要修改饿了么ui上传成功的状态位 找到本地临时储存的图片 把本地图片的url地址(bold本地地址)替换成腾讯云返回的图片地址(需要拼接 http://)
          if (data.statusCode === 200) { // 判断返回的状态位 200是上传成功
            const imgInfo = this.fileList.find(item => { // 进行筛选 筛选返回的图片uid和本地临时储存的uid是否一致
              // 比对服务器返回的uid 和 本地临时图片的uid
              return item.uid === params.file.uid
            })
            // 修改图片上传成功的状态位
            imgInfo.status = 'success'
            // 替换本地图片的临时地址(使用腾讯云地址需要拼接 http:// )
            imgInfo.url = 'https://' + data.Location // data.Location腾讯云返回的 图片地址(需要拼接http://)
          }
        })
      }
    },
    // 配置上传前的校验, 只要通过校验, 才能进行上传
    // 选择文件之前进行验证
    beforeUpload (file) { // 参数是图片的大小和类型进行效验
      // 检测文件的类型(仅支持 png jpg gif)
      const types = ['image/png', 'image/jpeg', 'image/gif']
      if (!types.includes(file.type)) { // 进行取反 true时候终止代码(返回的是false)
        // 不支持的格式进行提示
        this.$message.error('必须上传png,jpeg,gif三种类型之一')
        // 返回false 终止代码
        return false
      }
      // 检测文件的大小(限制1M以内)
      // file.size是获取图片的大小(字节的大小)
      if (file.size / 1024 / 1024 > 1) { // 计算文件大小 1MB=1024KB=1024×1024B=1048576B 总字节数 % 1024字节 % 1024kb
        this.$message.error('图片不可以超过1M')
        return false
      }
      return true
    },
    // 设置添加时候的功能
    handleChange (file, fileList) {
      // 添加图片后，该函数会触发
      // file 表示新选中的文件
      // fileList 表示选中之后剩余的列表(包含图片地址)
      this.fileList = fileList // 把添加添加图片后的列表信息储存起来
    },
    // 设置删除时候的功能
    handleRemove (file, fileList) {
      // 删除图片时触发: 需要变更fileList的值
      // file表示当前删除的图片信息
      // fileList表示删除后剩余的图片信息(删除后的信息)
      this.fileList = fileList // 把删除后的图片信息列表储存起来(空的图片信息列表)
    },
    // 接收组件传来的图片信息
    preview (file) {
      // 把略缩图的图片地址 设置为参数传来的头像地址
      this.imgUrl = file.url
      // 控制弹窗显示
      this.showDialog = true
    }
  }
}
</script>
<style lang="scss" scoped>
.my-img-upload {
  width: 500px;
  .hide-plus {
    // ::v-deep是sass覆盖原来的css样式的方法 less是/deep/
    ::v-deep .el-upload--picture-card {
      display: none;
    }
  }
}
</style>
